using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

 public class ShaderCollection : EditorWindow
    {
        private ShaderVariantCollection svc;
        static string toolsSVCpath = "Assets/Resource/Shaders/Tools.shadervariants";
        static ShaderVariantCollection ToolSVC = null;
        static List<string> allShaderNameList = new List<string>();
        /// <summary>
        /// 简单收集
        /// </summary>
        public static void SimpleGenShaderVariant(string shaderpath)
        {
            //先搜集所有keyword到工具类SVC
            ToolSVC = new ShaderVariantCollection();
            var shaders = AssetDatabase.FindAssets("t:Shader").ToList();
            foreach (var shader in shaders)
            {
                ShaderVariantCollection.ShaderVariant sv = new ShaderVariantCollection.ShaderVariant();
                var shaderPath = AssetDatabase.GUIDToAssetPath(shader);
                sv.shader = AssetDatabase.LoadAssetAtPath<Shader>(shaderPath);
                ToolSVC.Add(sv);
                //
                allShaderNameList.Add(shaderPath);
            }


            //防空
            var dirt = Path.GetDirectoryName(toolsSVCpath);
            if (!Directory.Exists(dirt))
            {
                Directory.CreateDirectory(dirt);
            }

            AssetDatabase.CreateAsset(ToolSVC, toolsSVCpath);



            var assets = AssetDatabase.FindAssets("t:Prefab").ToList();
            var assets2 = AssetDatabase.FindAssets("t:Material");
            assets.AddRange(assets2);
            List<string> allMatPaths = new List<string>();

            //GUID to assetPath
            for (int i = 0; i < assets.Count; i++)
            {
                var path = AssetDatabase.GUIDToAssetPath(assets[i]);
                //获取依赖中的mat
                var dependenciesPath = AssetDatabase.GetDependencies(path, true);
                var mats = dependenciesPath.ToList().FindAll((dp) => AssetDatabase.GetMainAssetTypeAtPath(dp) == typeof(Material));
                allMatPaths.AddRange(mats);
            }

            allMatPaths = allMatPaths.Distinct().ToList();
            ShaderVariantCollection allShaderVaraint = null;

            //收集ShaderVaraint
            var tools = new ShaderVariantsCollectionTools();
            allShaderVaraint = tools.CollectionKeywords(allMatPaths.ToArray(), ToolSVC);

            #region 老版本
            // foreach (var matPath in allMatPaths)
            // {
            //     var obj = AssetDatabase.LoadMainAssetAtPath(matPath);
            //     if (obj is Material)
            //     {
            //         var mat = obj as Material;
            //         AddToDict(mat);
            //     }
            // }
            // //所有shader输出的 varaint
            // var keys = ShaderVariantDict.Keys.ToList();
            // keys.Sort(StringComparer.Ordinal);
            // foreach (var key in keys)
            // {
            //     var shaderVariants = ShaderVariantDict[key];
            //     foreach (var sv in shaderVariants)
            //     {
            //         allShaderVaraint.Add(sv);
            //     }
            // }

            #endregion


            var targetDir = Path.GetDirectoryName(shaderpath);
            if (!Directory.Exists(targetDir))
            {
                Directory.CreateDirectory(targetDir);
            }

            AssetDatabase.DeleteAsset(shaderpath);
            AssetDatabase.CreateAsset(allShaderVaraint,shaderpath);
            AssetDatabase.Refresh();

            // var dependencies = AssetDatabase.GetDependencies(BResources.ALL_SHADER_VARAINT_ASSET_PATH);
            // foreach (var guid in dependencies )
            // {
            //     Debug.Log("依赖shader:" + guid);
            // }
        }
        
 #region 废弃代码

//         public class ShaderData
//         {
//             public int[] PassTypes = new int[] { };
//             public string[][] KeyWords = new string[][] { };
//             public string[] ReMainingKeyWords = new string[] { };
//         }
//
//         //shader数据的缓存
//         static Dictionary<string, ShaderData> ShaderDataDict = new Dictionary<string, ShaderData>();
//
//         static Dictionary<string, List<ShaderVariantCollection.ShaderVariant>> ShaderVariantDict = new Dictionary<string, List<ShaderVariantCollection.ShaderVariant>>();
//
//         //添加Material计算
//         static List<string> passShaderList = new List<string>();
//
//         /// <summary>
//         /// 添加到Dictionary
//         /// </summary>
//         /// <param name="curMat"></param>
//         static void AddToDict(Material curMat)
//         {
//             if (!curMat || !curMat.shader) return;
//
//             var shaderPath = AssetDatabase.GetAssetPath(curMat.shader);
//
//             // var runtimeDirects = BDApplication.GetAllRuntimeDirects().Select((r)=>r.Replace( "/Runtime","")).ToList();
//             // var result         = runtimeDirects.Find((r) => shaderPath.StartsWith(r, StringComparison.OrdinalIgnoreCase));
//             // if (result == null)
//             // {
//             //     Debug.LogErrorFormat("【收集ShaderKW】shader有可能引用出错:{0}-{1}" , curMat.name,shaderPath);
//             // }
//
//             if (!allShaderNameList.Contains(shaderPath))
//             {
//                 //  Debug.LogError("不存在shader:" + curMat.shader.name);
//                 // Debug.Log(shaderPath);
//                 return;
//             }
//
//
//             ShaderDataDict.TryGetValue(curMat.shader.name, out var sd);
//             if (sd == null)
//             {
//                 //一次性取出所有的 passtypes 和  keywords
//                 sd = GetShaderKeywords(curMat.shader);
//                 ShaderDataDict[curMat.shader.name] = sd;
//             }
//
//             var kwCount = sd.PassTypes.Length;
//             if (kwCount > 2000)
//             {
//                 if (!passShaderList.Contains(curMat.shader.name))
//                 {
//                     Debug.LogFormat("Shader【{0}】,变体数量:{1},不建议继续分析,后续也会跳过!", curMat.shader.name, kwCount);
//                     passShaderList.Add(curMat.shader.name);
//                 }
//                 else
//                 {
//                     Debug.LogFormat("mat:{0} , shader:{1} ,keywordCount:{2}", curMat.name, curMat.shader.name, kwCount);
//                 }
//
//                 return;
//             }
//
//             //变体增加规则：https://blog.csdn.net/RandomXM/article/details/88642534
//             List<ShaderVariantCollection.ShaderVariant> svlist = null;
//             if (!ShaderVariantDict.TryGetValue(curMat.shader.name, out svlist))
//             {
//                 svlist = new List<ShaderVariantCollection.ShaderVariant>();
//                 ShaderVariantDict[curMat.shader.name] = svlist;
//             }
//
//             //求所有mat的kw
//             for (int i = 0; i < sd.PassTypes.Length; i++)
//             {
//                 //
//                 var pt = (PassType) sd.PassTypes[i];
//                 ShaderVariantCollection.ShaderVariant? sv = null;
//                 try
//                 {
//                     if (curMat.shaderKeywords.Length > 0)
//                     {
//                         //变体交集 大于0 ，添加到 svcList
//                         sv = new ShaderVariantCollection.ShaderVariant(curMat.shader, pt, curMat.shaderKeywords);
//                     }
//                     else
//                     {
//                         sv = new ShaderVariantCollection.ShaderVariant(curMat.shader, pt);
//                     }
//                 }
//                 catch (Exception e)
//                 {
//                     Debug.LogWarning(string.Format("{0}-当前shader不存在变体（可以无视）:{1}-{2}", curMat.name, pt, JsonMapper.ToJson(curMat.shaderKeywords)));
//                     continue;
//                 }
//
//                 //判断sv 是否存在,不存在则添加
//                 if (sv != null)
//                 {
//                     bool isContain = false;
//                     var _sv = (ShaderVariantCollection.ShaderVariant) sv;
//                     foreach (var val in svlist)
//                     {
//                         if (val.passType == _sv.passType && System.Linq.Enumerable.SequenceEqual(val.keywords, _sv.keywords))
//                         {
//                             isContain = true;
//                             break;
//                         }
//                     }
//
//                     if (!isContain)
//                     {
//                         svlist.Add(_sv);
//                     }
//                 }
//             }
//         }
//
//
//         static MethodInfo GetShaderVariantEntries = null;
//
//
//         //获取shader的 keywords
//         public static ShaderData GetShaderKeywords(Shader shader)
//         {
//             ShaderData sd = new ShaderData();
//             GetShaderVariantEntriesFiltered(shader, new string[] { }, out sd.PassTypes, out sd.KeyWords, out sd.ReMainingKeyWords);
//             return sd;
//         }
//
//         /// <summary>
//         /// 获取keyword
//         /// </summary>
//         /// <param name="shader"></param>
//         /// <param name="filterKeywords"></param>
//         /// <param name="passTypes"></param>
//         /// <param name="keywordLists"></param>
//         /// <param name="remainingKeywords"></param>
//         static void GetShaderVariantEntriesFiltered(Shader shader, string[] filterKeywords, out int[] passTypes, out string[][] keywordLists, out string[] remainingKeywords)
//         {
//             //2019.3接口
// //            internal static void GetShaderVariantEntriesFiltered(
// //                Shader                  shader,                     0
// //                int                     maxEntries,                 1
// //                string[]                filterKeywords,             2
// //                ShaderVariantCollection excludeCollection,          3
// //                out int[]               passTypes,                  4
// //                out string[]            keywordLists,               5
// //                out string[]            remainingKeywords)          6
//             if (GetShaderVariantEntries == null)
//             {
//                 GetShaderVariantEntries = typeof(ShaderUtil).GetMethod("GetShaderVariantEntriesFiltered", BindingFlags.NonPublic | BindingFlags.Static);
//             }
//
//             passTypes = new int[] { };
//             keywordLists = new string[][] { };
//             remainingKeywords = new string[] { };
//             if (ToolSVC != null)
//             {
//                 var _passtypes = new int[] { };
//                 var _keywords = new string[] { };
//                 var _remainingKeywords = new string[] { };
//                 object[] args = new object[] {shader, 256, filterKeywords, ToolSVC, _passtypes, _keywords, _remainingKeywords};
//                 GetShaderVariantEntries.Invoke(null, args);
//
//                 var passtypes = args[4] as int[];
//                 passTypes = passtypes;
//                 //key word
//                 keywordLists = new string[passtypes.Length][];
//                 var kws = args[5] as string[];
//                 for (int i = 0; i < passtypes.Length; i++)
//                 {
//                     keywordLists[i] = kws[i].Split(' ');
//                 }
//
//                 //Remaning key word
//                 var rnkws = args[6] as string[];
//                 remainingKeywords = rnkws;
//             }
//         }

        #endregion
    }
